1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.collect;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21 import static com.google.common.collect.Maps.keyOrNull;
22
23 import com.google.common.annotations.GwtCompatible;
24
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.Comparator;
28 import java.util.Map;
29 import java.util.NavigableMap;
30 import java.util.SortedMap;
31 import java.util.TreeMap;
32
33 import javax.annotation.Nullable;
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 @GwtCompatible(serializable = true, emulated = true)
59 public abstract class ImmutableSortedMap<K, V>
60 extends ImmutableSortedMapFauxverideShim<K, V> implements NavigableMap<K, V> {
61
62
63
64
65 private static final Comparator<Comparable> NATURAL_ORDER = Ordering.natural();
66
67 private static final ImmutableSortedMap<Comparable, Object> NATURAL_EMPTY_MAP =
68 new EmptyImmutableSortedMap<Comparable, Object>(NATURAL_ORDER);
69
70 static <K, V> ImmutableSortedMap<K, V> emptyMap(Comparator<? super K> comparator) {
71 if (Ordering.natural().equals(comparator)) {
72 return of();
73 } else {
74 return new EmptyImmutableSortedMap<K, V>(comparator);
75 }
76 }
77
78 static <K, V> ImmutableSortedMap<K, V> fromSortedEntries(
79 Comparator<? super K> comparator,
80 int size,
81 Entry<K, V>[] entries) {
82 if (size == 0) {
83 return emptyMap(comparator);
84 }
85
86 ImmutableList.Builder<K> keyBuilder = ImmutableList.builder();
87 ImmutableList.Builder<V> valueBuilder = ImmutableList.builder();
88 for (int i = 0; i < size; i++) {
89 Entry<K, V> entry = entries[i];
90 keyBuilder.add(entry.getKey());
91 valueBuilder.add(entry.getValue());
92 }
93
94 return new RegularImmutableSortedMap<K, V>(
95 new RegularImmutableSortedSet<K>(keyBuilder.build(), comparator),
96 valueBuilder.build());
97 }
98
99 static <K, V> ImmutableSortedMap<K, V> from(
100 ImmutableSortedSet<K> keySet, ImmutableList<V> valueList) {
101 if (keySet.isEmpty()) {
102 return emptyMap(keySet.comparator());
103 } else {
104 return new RegularImmutableSortedMap<K, V>(
105 (RegularImmutableSortedSet<K>) keySet,
106 valueList);
107 }
108 }
109
110
111
112
113 @SuppressWarnings("unchecked")
114
115
116 public static <K, V> ImmutableSortedMap<K, V> of() {
117 return (ImmutableSortedMap<K, V>) NATURAL_EMPTY_MAP;
118 }
119
120
121
122
123 public static <K extends Comparable<? super K>, V>
124 ImmutableSortedMap<K, V> of(K k1, V v1) {
125 return from(ImmutableSortedSet.of(k1), ImmutableList.of(v1));
126 }
127
128
129
130
131
132
133
134
135 @SuppressWarnings("unchecked")
136 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
137 of(K k1, V v1, K k2, V v2) {
138 return fromEntries(Ordering.natural(), false, 2, entryOf(k1, v1), entryOf(k2, v2));
139 }
140
141
142
143
144
145
146
147
148 @SuppressWarnings("unchecked")
149 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
150 of(K k1, V v1, K k2, V v2, K k3, V v3) {
151 return fromEntries(Ordering.natural(), false, 3, entryOf(k1, v1), entryOf(k2, v2),
152 entryOf(k3, v3));
153 }
154
155
156
157
158
159
160
161
162 @SuppressWarnings("unchecked")
163 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
164 of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
165 return fromEntries(Ordering.natural(), false, 4, entryOf(k1, v1), entryOf(k2, v2),
166 entryOf(k3, v3), entryOf(k4, v4));
167 }
168
169
170
171
172
173
174
175
176 @SuppressWarnings("unchecked")
177 public static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
178 of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
179 return fromEntries(Ordering.natural(), false, 5, entryOf(k1, v1), entryOf(k2, v2),
180 entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5));
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 public static <K, V> ImmutableSortedMap<K, V> copyOf(
201 Map<? extends K, ? extends V> map) {
202
203
204 @SuppressWarnings("unchecked")
205 Ordering<K> naturalOrder = (Ordering<K>) Ordering.<Comparable>natural();
206 return copyOfInternal(map, naturalOrder);
207 }
208
209
210
211
212
213
214
215
216
217
218
219
220
221 public static <K, V> ImmutableSortedMap<K, V> copyOf(
222 Map<? extends K, ? extends V> map, Comparator<? super K> comparator) {
223 return copyOfInternal(map, checkNotNull(comparator));
224 }
225
226
227
228
229
230
231
232
233
234
235
236 @SuppressWarnings("unchecked")
237 public static <K, V> ImmutableSortedMap<K, V> copyOfSorted(
238 SortedMap<K, ? extends V> map) {
239 Comparator<? super K> comparator = map.comparator();
240 if (comparator == null) {
241
242
243 comparator = (Comparator<? super K>) NATURAL_ORDER;
244 }
245 return copyOfInternal(map, comparator);
246 }
247
248 private static <K, V> ImmutableSortedMap<K, V> copyOfInternal(
249 Map<? extends K, ? extends V> map, Comparator<? super K> comparator) {
250 boolean sameComparator = false;
251 if (map instanceof SortedMap) {
252 SortedMap<?, ?> sortedMap = (SortedMap<?, ?>) map;
253 Comparator<?> comparator2 = sortedMap.comparator();
254 sameComparator = (comparator2 == null)
255 ? comparator == NATURAL_ORDER
256 : comparator.equals(comparator2);
257 }
258
259 if (sameComparator && (map instanceof ImmutableSortedMap)) {
260
261
262 @SuppressWarnings("unchecked")
263 ImmutableSortedMap<K, V> kvMap = (ImmutableSortedMap<K, V>) map;
264 if (!kvMap.isPartialView()) {
265 return kvMap;
266 }
267 }
268
269
270
271
272 @SuppressWarnings("unchecked")
273 Entry<K, V>[] entries = map.entrySet().toArray(new Entry[0]);
274
275 return fromEntries(comparator, sameComparator, entries.length, entries);
276 }
277
278 static <K, V> ImmutableSortedMap<K, V> fromEntries(
279 Comparator<? super K> comparator, boolean sameComparator, int size, Entry<K, V>... entries) {
280 for (int i = 0; i < size; i++) {
281 Entry<K, V> entry = entries[i];
282 entries[i] = entryOf(entry.getKey(), entry.getValue());
283 }
284 if (!sameComparator) {
285 sortEntries(comparator, size, entries);
286 validateEntries(size, entries, comparator);
287 }
288
289 return fromSortedEntries(comparator, size, entries);
290 }
291
292 private static <K, V> void sortEntries(
293 final Comparator<? super K> comparator, int size, Entry<K, V>[] entries) {
294 Arrays.sort(entries, 0, size, Ordering.from(comparator).<K>onKeys());
295 }
296
297 private static <K, V> void validateEntries(int size, Entry<K, V>[] entries,
298 Comparator<? super K> comparator) {
299 for (int i = 1; i < size; i++) {
300 checkNoConflict(comparator.compare(entries[i - 1].getKey(), entries[i].getKey()) != 0, "key",
301 entries[i - 1], entries[i]);
302 }
303 }
304
305
306
307
308
309
310 public static <K extends Comparable<?>, V> Builder<K, V> naturalOrder() {
311 return new Builder<K, V>(Ordering.natural());
312 }
313
314
315
316
317
318
319
320
321
322 public static <K, V> Builder<K, V> orderedBy(Comparator<K> comparator) {
323 return new Builder<K, V>(comparator);
324 }
325
326
327
328
329
330 public static <K extends Comparable<?>, V> Builder<K, V> reverseOrder() {
331 return new Builder<K, V>(Ordering.natural().reverse());
332 }
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354 public static class Builder<K, V> extends ImmutableMap.Builder<K, V> {
355 private final Comparator<? super K> comparator;
356
357
358
359
360
361 @SuppressWarnings("unchecked")
362 public Builder(Comparator<? super K> comparator) {
363 this.comparator = checkNotNull(comparator);
364 }
365
366
367
368
369
370
371 @Override public Builder<K, V> put(K key, V value) {
372 super.put(key, value);
373 return this;
374 }
375
376
377
378
379
380
381
382
383
384 @Override public Builder<K, V> put(Entry<? extends K, ? extends V> entry) {
385 super.put(entry);
386 return this;
387 }
388
389
390
391
392
393
394
395
396 @Override public Builder<K, V> putAll(Map<? extends K, ? extends V> map) {
397 super.putAll(map);
398 return this;
399 }
400
401
402
403
404
405
406
407 @Override public ImmutableSortedMap<K, V> build() {
408 return fromEntries(comparator, false, size, entries);
409 }
410 }
411
412 ImmutableSortedMap() {
413 }
414
415 ImmutableSortedMap(ImmutableSortedMap<K, V> descendingMap) {
416 this.descendingMap = descendingMap;
417 }
418
419 @Override
420 public int size() {
421 return values().size();
422 }
423
424 @Override public boolean containsValue(@Nullable Object value) {
425 return values().contains(value);
426 }
427
428 @Override boolean isPartialView() {
429 return keySet().isPartialView() || values().isPartialView();
430 }
431
432
433
434
435
436 @Override public ImmutableSet<Entry<K, V>> entrySet() {
437 return super.entrySet();
438 }
439
440
441
442
443 @Override public abstract ImmutableSortedSet<K> keySet();
444
445
446
447
448
449 @Override public abstract ImmutableCollection<V> values();
450
451
452
453
454
455
456
457 @Override
458 public Comparator<? super K> comparator() {
459 return keySet().comparator();
460 }
461
462 @Override
463 public K firstKey() {
464 return keySet().first();
465 }
466
467 @Override
468 public K lastKey() {
469 return keySet().last();
470 }
471
472
473
474
475
476
477
478
479
480
481
482 @Override
483 public ImmutableSortedMap<K, V> headMap(K toKey) {
484 return headMap(toKey, false);
485 }
486
487
488
489
490
491
492
493
494
495
496
497
498
499 @Override
500 public abstract ImmutableSortedMap<K, V> headMap(K toKey, boolean inclusive);
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515 @Override
516 public ImmutableSortedMap<K, V> subMap(K fromKey, K toKey) {
517 return subMap(fromKey, true, toKey, false);
518 }
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535 @Override
536 public ImmutableSortedMap<K, V> subMap(K fromKey, boolean fromInclusive, K toKey,
537 boolean toInclusive) {
538 checkNotNull(fromKey);
539 checkNotNull(toKey);
540 checkArgument(comparator().compare(fromKey, toKey) <= 0,
541 "expected fromKey <= toKey but %s > %s", fromKey, toKey);
542 return headMap(toKey, toInclusive).tailMap(fromKey, fromInclusive);
543 }
544
545
546
547
548
549
550
551
552
553
554
555 @Override
556 public ImmutableSortedMap<K, V> tailMap(K fromKey) {
557 return tailMap(fromKey, true);
558 }
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573 @Override
574 public abstract ImmutableSortedMap<K, V> tailMap(K fromKey, boolean inclusive);
575
576 @Override
577 public Entry<K, V> lowerEntry(K key) {
578 return headMap(key, false).lastEntry();
579 }
580
581 @Override
582 public K lowerKey(K key) {
583 return keyOrNull(lowerEntry(key));
584 }
585
586 @Override
587 public Entry<K, V> floorEntry(K key) {
588 return headMap(key, true).lastEntry();
589 }
590
591 @Override
592 public K floorKey(K key) {
593 return keyOrNull(floorEntry(key));
594 }
595
596 @Override
597 public Entry<K, V> ceilingEntry(K key) {
598 return tailMap(key, true).firstEntry();
599 }
600
601 @Override
602 public K ceilingKey(K key) {
603 return keyOrNull(ceilingEntry(key));
604 }
605
606 @Override
607 public Entry<K, V> higherEntry(K key) {
608 return tailMap(key, false).firstEntry();
609 }
610
611 @Override
612 public K higherKey(K key) {
613 return keyOrNull(higherEntry(key));
614 }
615
616 @Override
617 public Entry<K, V> firstEntry() {
618 return isEmpty() ? null : entrySet().asList().get(0);
619 }
620
621 @Override
622 public Entry<K, V> lastEntry() {
623 return isEmpty() ? null : entrySet().asList().get(size() - 1);
624 }
625
626
627
628
629
630
631
632 @Deprecated
633 @Override
634 public final Entry<K, V> pollFirstEntry() {
635 throw new UnsupportedOperationException();
636 }
637
638
639
640
641
642
643
644 @Deprecated
645 @Override
646 public final Entry<K, V> pollLastEntry() {
647 throw new UnsupportedOperationException();
648 }
649
650 private transient ImmutableSortedMap<K, V> descendingMap;
651
652 @Override
653 public ImmutableSortedMap<K, V> descendingMap() {
654 ImmutableSortedMap<K, V> result = descendingMap;
655 if (result == null) {
656 result = descendingMap = createDescendingMap();
657 }
658 return result;
659 }
660
661 abstract ImmutableSortedMap<K, V> createDescendingMap();
662
663 @Override
664 public ImmutableSortedSet<K> navigableKeySet() {
665 return keySet();
666 }
667
668 @Override
669 public ImmutableSortedSet<K> descendingKeySet() {
670 return keySet().descendingSet();
671 }
672
673
674
675
676
677
678
679 private static class SerializedForm extends ImmutableMap.SerializedForm {
680 private final Comparator<Object> comparator;
681 @SuppressWarnings("unchecked")
682 SerializedForm(ImmutableSortedMap<?, ?> sortedMap) {
683 super(sortedMap);
684 comparator = (Comparator<Object>) sortedMap.comparator();
685 }
686 @Override Object readResolve() {
687 Builder<Object, Object> builder = new Builder<Object, Object>(comparator);
688 return createMap(builder);
689 }
690 private static final long serialVersionUID = 0;
691 }
692
693 @Override Object writeReplace() {
694 return new SerializedForm(this);
695 }
696
697
698
699 private static final long serialVersionUID = 0;
700 }